import React, { useEffect, useRef, useState } from 'react';
import { Form, Row, Col, message, Button, Modal, Input } from 'antd';
import { SketchPicker, CompactPicker } from 'react-color';
import styles from './index.module.scss';
import { getInitArt, saveTempArt, saveArt, cleanCanvas } from './service';
import { useRequest } from 'ahooks';
import config from '@/api/GlobalConfig';

const layout = {
  labelCol: { span: 6 },
  wrapperCol: { span: 18 },
};

function Run(this: any, canvas) {
  this.canvas = canvas;
  this.cvs = canvas.getContext('2d');
  this.bgColor = '#f0f0f0';
  this.clickedColor = '#ff0000';
  this.boxSize = document.body.clientWidth > 1200 ? 12 : 10;
  this.bgWidthLength = 0; // 宽的块数
  this.bgHeightLength = 0; // 高德块数
  this.clickedArr = [];
  this.start();
  this.click();
  // return this;
}
Run.prototype.start = function () {
  this.bgWidthLength = Math.floor(this.canvas.width / this.boxSize);
  this.bgHeightLength = Math.floor(this.canvas.height / this.boxSize);
  this.cvs.fillStyle = '#fff';
  this.cvs.fillRect(0, 0, this.canvas.width, this.canvas.height);
  this.drawBg();
};

Run.prototype.mousemove = function (e) {
  const pixelBlock = this.computedXY(e.offsetX, e.offsetY);
  this.toggleClick(pixelBlock, true); // true 滑动经过时，不擦色
};

Run.prototype.click = function () {
  const move = this.mousemove.bind(this);
  /**
   * 监听按下绘制，并监听按下滑动绘制
   */
  this.canvas.addEventListener(
    'mousedown',
    function (e) {
      console.log(this.computedXY(e.offsetX, e.offsetY));
      const o = this.computedXY(e.offsetX, e.offsetY);
      this.toggleClick(o);
      this.canvas.addEventListener('mousemove', move);
    }.bind(this),
  );

  this.canvas.addEventListener(
    'mouseup',
    function (e) {
      this.canvas.removeEventListener('mousemove', move);
    }.bind(this),
  );
};
/**
 * 将offsetX,offsetY转化为canvas坐标
 */
Run.prototype.computedXY = function (x: number, y: number) {
  let computedX;
  let computedY;
  for (let i = 0; i < this.bgWidthLength; i++) {
    if (x > i * this.boxSize && x < (i + 1) * this.boxSize) {
      computedX = i;
      break;
    }
  }
  for (let i = 0; i < this.bgHeightLength; i++) {
    if (y > i * this.boxSize && y < (i + 1) * this.boxSize) {
      computedY = i;
      break;
    }
  }
  return { x: computedX, y: computedY, color: this.clickedColor };
};
/**
 * 点击像素块，切换颜色
 * @param draw 是否有色
 */
Run.prototype.toggleClick = function (pixelBlock: { x: number; y: number; color: string }, draw?: boolean) {
  const has = { is: true, index: null };

  this.clickedArr.forEach((item, index) => {
    if (item.x === pixelBlock.x && item.y === pixelBlock.y) {
      has.is = false;
      has.index = index;
    }
  });
  // 此像素块未涂色
  if (has.is && pixelBlock.x !== undefined && pixelBlock.y !== undefined) {
    this.clickedArr.push(pixelBlock);
    this.drawBgBox(pixelBlock.x * this.boxSize, pixelBlock.y * this.boxSize, true);
  }
  // 此色块已涂色，点击恢复背景色
  if (!has.is && !draw) {
    this.clickedArr.splice(has.index, 1);
    this.drawBgBox(pixelBlock.x * this.boxSize, pixelBlock.y * this.boxSize);
  }
};

Run.prototype.clean = function () {
  this.clickedArr.forEach(
    function (item) {
      this.drawBgBox(item.x * this.boxSize, item.y * this.boxSize);
    }.bind(this),
  );

  this.clickedArr = [];
};
Run.prototype.drawBg = function () {
  for (let i = 0; i < this.bgHeightLength; i++) {
    for (let j = 0; j < this.bgWidthLength; j++) {
      this.drawBgBox(j * this.boxSize, i * this.boxSize);
    }
  }
};
/**
 * 改变背景颜色
 */
Run.prototype.changeBgColor = function () {
  for (let i = 0; i < this.bgHeightLength; i++) {
    for (let j = 0; j < this.bgWidthLength; j++) {
      const has = { is: false, index: null };
      /**
       * 检查当前色块是否是已涂色块
       */
      this.clickedArr.forEach((item, index) => {
        if (item.x === i && item.y === j) {
          has.is = true;
          has.index = index;
        }
      });
      // 未涂为背景色块
      if (!has.is) {
        this.drawBgBox(i * this.boxSize, j * this.boxSize);
      }
    }
  }
};

Run.prototype.drawBgBox = function (x: number, y: number, fillClickedColor: boolean) {
  this.cvs.beginPath();
  this.cvs.fillStyle = fillClickedColor ? this.clickedColor : this.bgColor;
  this.cvs.fillRect(x + 1, y + 1, this.boxSize - 1, this.boxSize - 1); // 绘制每个像素点
  this.cvs.fill();
  this.cvs.stroke();
  this.cvs.closePath();
};

Run.prototype.saveImg = function () {
  return this.canvas.toDataURL('image/jpeg', 1);
};

Run.prototype.initArt = function () {
  for (let i = 0; i < this.bgHeightLength; i++) {
    for (let j = 0; j < this.bgWidthLength; j++) {
      const has = { is: false, index: null };
      /**
       * 检查当前色块是否是已涂色块
       */
      this.clickedArr.forEach((item, index) => {
        if (item.x === i && item.y === j) {
          has.is = true;
          has.index = index;
          this.cvs.beginPath();
          this.cvs.fillStyle = item.color;
          this.cvs.fillRect(i * this.boxSize + 1, j * this.boxSize + 1, this.boxSize - 1, this.boxSize - 1); // 绘制每个像素点
          this.cvs.fill();
          this.cvs.stroke();
          this.cvs.closePath();
        }
      });
      // 未涂为背景色块
      if (!has.is) {
        this.drawBgBox(i * this.boxSize, j * this.boxSize);
      }
    }
  }
};

export default function Create() {
  const [canvasObj, setCanvasObj] = useState<any>();
  const [clickedColor, setClickedColor] = useState('#fff');
  const [bgColor, setBgColor] = useState('#f0f0f0');
  const [showModal, setShowModal] = useState(false);
  const [form] = Form.useForm();
  const { data, loading, error } = useRequest(() => getInitArt(), {
    onSuccess: () => {
      if (data?.clickedColor.length !== 0 && data) {
        console.log(canvasObj);
        setBgColor(data.bgColor);
        canvasObj.bgColor = data.bgColor;
        canvasObj.clickedArr = data.clickedColor;
        canvasObj.initArt();
      } else if (data) {
        setBgColor(data.bgColor);
        canvasObj.bgColor = data.bgColor;
        canvasObj.changeBgColor();
      }
    },
  });
  useEffect(() => {
    /* eslint-disable no-new */
    // eslint-disable-next-line new-cap
    const canvas: any = document.querySelector('.main canvas');

    setCanvasObj(new Run(canvas)); // canvas的实例化对象
  }, []);
  // 处理颜色变化函数
  const handleChangeComplete = (color) => {
    setClickedColor(color.hex);
    canvasObj.clickedColor = color.hex;
  };
  const handleBgChangeComplete = (color) => {
    setBgColor(color.hex);
    canvasObj.bgColor = color.hex;
    // canvasObj.drawBg();
    canvasObj.changeBgColor();
  };

  const postArtInfoForm = async () => {
    form.validateFields().then(async (values: { name: string; description: string }) => {
      await saveTempArt({ bgColor, clickedColor: canvasObj.clickedArr });

      setShowModal(false);

      message.success('保存图片成功');

      const res = await saveArt(values);

      window.open(`${config.imageUrl}${res.url}`);
    });
  };
  return (
    <Row className="main" justify="space-between" style={{ width: '100%', marginBottom: 20 }}>
      <Col span={17}>
        <canvas
          width={document.body.clientWidth > 1200 ? 768 : 640}
          height={document.body.clientWidth > 1200 ? 768 : 640}
        />
      </Col>
      <Col span={6}>
        <div className={styles.canvas}>
          <div style={{ marginTop: 10, marginBottom: 10 }}>画笔颜色：</div>
          <SketchPicker color={clickedColor} onChangeComplete={handleChangeComplete} />
          <div style={{ marginTop: 10, marginBottom: 10 }}>背景颜色：</div>
          <CompactPicker color={bgColor} onChangeComplete={handleBgChangeComplete} />
          {/* <div style={{ marginTop: 10, marginBottom: 10 }}>工具箱：</div> */}
          <Button
            style={{ marginTop: 20 }}
            onClick={() => {
              canvasObj.clean();
              cleanCanvas({ bgColor });
            }}
          >
            清除
          </Button>

          <Button
            style={{ marginTop: 20 }}
            onClick={async () => {
              // console.log(canvasObj);
              // console.log({ bgColor, clickedColor: canvasObj.clickedArr });
              await saveTempArt({ bgColor, clickedColor: canvasObj.clickedArr });
              message.success('暂存成功，下次可继续编辑');
            }}
          >
            暂存
          </Button>

          <Button
            type="primary"
            style={{ marginTop: 20 }}
            // ghost
            onClick={() => {
              setShowModal(true);
            }}
          >
            保存图片
          </Button>

          <Modal
            title="提交信息"
            visible={showModal}
            okText="提交"
            cancelText="取消"
            onOk={postArtInfoForm}
            onCancel={() => {
              setShowModal(false);
            }}
          >
            <Form {...layout} form={form}>
              <Form.Item name="name" label="作品名称" rules={[{ required: true, message: '请输入作品名称' }]}>
                <Input placeholder="请输入作品名称" />
              </Form.Item>
              <Form.Item name="description" label="作品描述" rules={[{ required: true, message: '作品描述，最少6个字哦~', min: 6 }]}>
                <Input.TextArea placeholder="请用简短的话来描述你的作品" />
              </Form.Item>
            </Form>
          </Modal>
        </div>
      </Col>
    </Row>
  );
}
